package com.bjpowernode.boss.web.service.impl;

import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.digest.DigestUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.bjpowernode.boss.common.cilent.RedisClient;
import com.bjpowernode.boss.common.constants.KeyConstants;
import com.bjpowernode.boss.common.enums.AjaxCode;
import com.bjpowernode.boss.common.error.BossException;
import com.bjpowernode.boss.db.domain.PmsMenu;
import com.bjpowernode.boss.db.domain.PmsOperator;
import com.bjpowernode.boss.db.mapper.PmsMenuMapper;
import com.bjpowernode.boss.db.mapper.PmsOperatorMapper;
import com.bjpowernode.boss.web.service.LoginService;
import com.bjpowernode.boss.web.models.dto.LoginDto;
import com.bjpowernode.boss.web.models.form.LoginForm;
import com.bjpowernode.boss.common.utils.JsonUtil;
import com.bjpowernode.boss.common.utils.JwtUtil;
import com.bjpowernode.boss.web.models.menus.SubMenu;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;

import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.TimeUnit;

@Service
public class LoginServiceImpl implements LoginService {
    @Resource
    private RedisClient redisClient;
    @Resource
    private PmsOperatorMapper pmsOperatorMapper;
    @Resource
    private PmsMenuMapper pmsMenuMapper;

    @Override
    public LoginDto loginCheck(LoginForm loginForm) {
        QueryWrapper<PmsOperator> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("login_name", loginForm.getLoginName());
        PmsOperator admin =pmsOperatorMapper.selectOne(queryWrapper);
        if(admin==null){
            throw new BossException(AjaxCode.LOGIN_USER_INVALID);
        }
        String loginPwd = DigestUtil.md5Hex(loginForm.getPassWord()+admin.getSalt());
        if(!loginPwd.equals(admin.getLoginPwd())){
            throw new BossException(AjaxCode.LOGIN_NAME_OR_PASSWORD_ERROR);
        }
        String jwt = JwtUtil.createJwt(JsonUtil.beanToJson(admin),120);
        Map<String,String> data = new HashMap<>();
        data.put("operatorId",String.valueOf(admin.getId()));
        data.put("jwt",jwt);
        data.put("loginTime",new SimpleDateFormat("yyyyMMddHHmmss").format(new Date()));
        boolean add = redisClient.setHashAll(KeyConstants.OPERATOR_LOGIN_JWT+admin.getId(), data, 120, TimeUnit.MINUTES);
        if(!add){
            throw new BossException(AjaxCode.LOGIN_TOKEN_SAVE_FAIL);
        }
        return new LoginDto(admin.getId(),jwt,admin.getShowName());
    }
    public List<SubMenu> getMenus(Long Id){
        List<SubMenu> subMenus;
        try {
            String key=KeyConstants.OPERATOR_MENUS+Id;
            String menuJSON=redisClient.getValue(key);
            if(StrUtil.isNotBlank(menuJSON)){
                subMenus = JSONUtil.toList(menuJSON, SubMenu.class);
            }else{
                synchronized (this) {
                    menuJSON= redisClient.getValue(key);
                    if(StrUtil.isNotBlank(menuJSON)){
                        subMenus=JSONUtil.toList(menuJSON, SubMenu.class);
                    }
                    else{
                        subMenus=getMenusFormDB(Id);
                        if(!subMenus.isEmpty()){
                            redisClient.setValue(key, JSONUtil.toJsonStr(subMenus));
                        }
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            subMenus = getMenusFormDB(Id);
        }
        return subMenus;
    }
    private List<SubMenu> getMenusFormDB(Long Id){
        List<PmsMenu> pmsMenus = pmsMenuMapper.selectMenusById(Id);
        List<SubMenu> subMenus = new ArrayList<>();
        for(PmsMenu p:pmsMenus){
            if ("NO".equals(p.getIsLeaf())) {
                SubMenu subMenu = new SubMenu();
                subMenu.setId(p.getId());
                subMenu.setIsLeaf(p.getIsLeaf());
                subMenu.setLevel(p.getLevel());
                subMenu.setParentId(p.getParentId());
                subMenu.setNumber(p.getNumber());
                subMenu.setName(p.getName());
                subMenu.setUrl(p.getUrl());
                subMenu.setRemark(p.getRemark());
                subMenu.setStatus(p.getStatus());
                subMenu.setEditTime(p.getEditTime());
                List<PmsMenu> menuItems = new ArrayList<>();
                for(PmsMenu pmsMenu:pmsMenus){
                    if(pmsMenu.getNumber().contains(p.getNumber())&&!"NO".equals(pmsMenu.getIsLeaf())){
                        menuItems.add(pmsMenu);
                    }
                }
                subMenu.setMenuItems(menuItems);
                subMenus.add(subMenu);
            }
        }
        return subMenus;
    }
}
